package com.ruoyi.system.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.pinyin.PinyinUtil;
import com.ruoyi.common.constant.ErrorConstants;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.enums.BaseEnum;
import com.ruoyi.common.exception.base.BaseException;
import com.ruoyi.common.utils.IDGenerator;
import com.ruoyi.system.dao.PmsArchivesDao;
import com.ruoyi.system.domain.dto.AmsFirstAidDto;
import com.ruoyi.system.domain.dto.FirstAidDto;
import com.ruoyi.system.domain.po.*;
import com.ruoyi.system.mapper.PmsArchivesMapper;
import com.ruoyi.system.mapper.PmsArchivesRecordMapper;
import com.ruoyi.system.service.AmsFirstAidService;
import com.ruoyi.system.service.TCodeServier;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

import static com.ruoyi.common.constant.UserConstants.QuestionCode.*;

@Slf4j
@Service
public class AmsFirstAidServiceImpl implements AmsFirstAidService {

    @Resource
    private PmsArchivesMapper pmsArchivesMapper;
    @Resource
    private PmsArchivesRecordMapper pmsArchivesRecordMapper;
    @Resource
    private TCodeServier tCodeServier;
    @Resource
    private PmsArchivesDao pmsArchivesDao;

    @Override
    public void postEmergencyRecord(FirstAidDto.Insert dto) {
        // 检查身份证号是否重复
        PmsArchivesExample pmsArchivesExample = new PmsArchivesExample();
        pmsArchivesExample.createCriteria().andDelFlagEqualTo((byte) 0).andIdCardEqualTo(dto.getPatientInfo().getIdcard());
        List<PmsArchives> pmsArchivesList = pmsArchivesMapper.selectByExample(pmsArchivesExample);
        if (!pmsArchivesList.isEmpty()) {
            throw new BaseException(ErrorConstants.DUPLICATE_ID_CARD);
        }
        // 新增实体数据
        long pmsArchivesId = IdUtil.getSnowflake().nextId();
        PmsArchives pmsArchives = BeanUtil.copyProperties(dto.getPatientInfo(), PmsArchives.class);
        pmsArchives.setId(pmsArchivesId);
        pmsArchives.setPinyinFull(PinyinUtil.getPinyin(pmsArchives.getName()));
        pmsArchives.setPinyinSimple(PinyinUtil.getFirstLetter(pmsArchives.getName(), ""));
//        pmsArchives.setCreateBy(SecurityUtils.getUsername());
        pmsArchives.setCreateTime(new Date());
        pmsArchives.setIdCard(dto.getPatientInfo().getIdcard());
        int i = pmsArchivesMapper.insertSelective(pmsArchives);
        // 新增溶栓记录
        List<FirstAidDto.Insert.RecordInfo> thrombolysis = dto.getThrombolysis();
        if (i > 0 && CollectionUtil.isNotEmpty(thrombolysis)) {
            thrombolysis.forEach(recordDto -> {
                PmsArchivesRecord pmsArchivesRecord = BeanUtil.copyProperties(recordDto, PmsArchivesRecord.class);
                pmsArchivesRecord.setId(IdUtil.getSnowflake().nextId());
                pmsArchivesRecord.setArchivesId(pmsArchivesId);
                pmsArchivesRecord.setCreatedAt(new Date());
                pmsArchivesRecord.setAnswer(recordDto.getValue());
                pmsArchivesRecord.setDelFlag((byte) 0);
                pmsArchivesRecord.setCode(recordDto.getCode());
                pmsArchivesRecordMapper.insertSelective(pmsArchivesRecord);
            });
        }

        // 新增溶栓记录
        List<FirstAidDto.Insert.RecordInfo> jznfo = dto.getJznfo();
        if (i > 0 && CollectionUtil.isNotEmpty(jznfo)) {
            jznfo.forEach(recordDto -> {
                PmsArchivesRecord pmsArchivesRecord = BeanUtil.copyProperties(recordDto, PmsArchivesRecord.class);
                pmsArchivesRecord.setId(IdUtil.getSnowflake().nextId());
                pmsArchivesRecord.setArchivesId(pmsArchivesId);
                pmsArchivesRecord.setCreatedAt(new Date());
                pmsArchivesRecord.setAnswer(recordDto.getValue());
                pmsArchivesRecord.setDelFlag((byte) 0);
                pmsArchivesRecord.setCode(recordDto.getCode());
                pmsArchivesRecordMapper.insertSelective(pmsArchivesRecord);
            });
        }

        // 新增溶栓记录
        List<FirstAidDto.Insert.RecordInfo> jrInfo = dto.getJrInfo();
        if (i > 0 && CollectionUtil.isNotEmpty(jrInfo)) {
            jrInfo.forEach(recordDto -> {
                PmsArchivesRecord pmsArchivesRecord = BeanUtil.copyProperties(recordDto, PmsArchivesRecord.class);
                pmsArchivesRecord.setId(IdUtil.getSnowflake().nextId());
                pmsArchivesRecord.setArchivesId(pmsArchivesId);
                pmsArchivesRecord.setCreatedAt(new Date());
                pmsArchivesRecord.setAnswer(recordDto.getValue());
                pmsArchivesRecord.setDelFlag((byte) 0);
                pmsArchivesRecord.setCode(recordDto.getCode());
                pmsArchivesRecordMapper.insertSelective(pmsArchivesRecord);
            });
        }
    }

    @Override
    public void postEmergencyRecordList(List<FirstAidDto.Insert> list) {
        list.forEach(this::postEmergencyRecord);
    }

    @Override
    public void saveAidRecord(AmsFirstAidDto.SaveAidRecord param) throws ParseException {
        //验证急救信息
        PmsArchives firstAid = validateFirstAidWhenModified(param.getFirstAidId());

        //验证问题和答案
        if (CollectionUtil.isEmpty(param.getCodeAndAnswerList())) {
            return;
        }
        //急救信息校验
        validateFirstAidRecords(param.getCodeAndAnswerList());
        //补充信息(有身高需要补充剂量)
        param.setCodeAndAnswerList(supplement(param.getCodeAndAnswerList()));

        //去重 因为有两条是否静脉溶栓的值
        List<AmsFirstAidDto.SaveAidRecord.CodeAndAnswer> codeAndAnswerList = param.getCodeAndAnswerList().stream().distinct().collect(Collectors.toList());

        //保存答案
        List<PmsArchivesRecord> willSavedFirstAidRecordList = CollectionUtil.newArrayList();
        for (AmsFirstAidDto.SaveAidRecord.CodeAndAnswer codeAndAnswer : codeAndAnswerList) {
            //code合法性判定
            if (null == tCodeServier.getCodeCache(codeAndAnswer.getQuestionCode())) {
                log.info("code不存在,{}", codeAndAnswer.getQuestionCode());
                throw new BaseException(ErrorConstants.QUESTION_CODE_NOT_FOUND, codeAndAnswer.getQuestionCode());
            }

            //添加新纪录
            if (StrUtil.isEmpty(codeAndAnswer.getAnswerString()) || "null".equals(codeAndAnswer.getAnswerString())) {
                continue;
            }

            //添加记录表，查找之前的记录，删除后重新添加
            PmsArchivesRecordExample recordExample = new PmsArchivesRecordExample();
            recordExample.createCriteria().andArchivesIdEqualTo(firstAid.getId())
                    .andCodeEqualTo(codeAndAnswer.getQuestionCode())
                    .andDelFlagEqualTo((byte) 0);
            List<PmsArchivesRecord> firstAidRecords = pmsArchivesRecordMapper.selectByExample(recordExample);
            if (CollectionUtil.isNotEmpty(firstAidRecords)) {
                firstAidRecords.forEach(e -> {
                    PmsArchivesRecord willDeletedRecord = new PmsArchivesRecord();
                    willDeletedRecord.setId(e.getId());
                    willDeletedRecord.setDelFlag((byte) 1);
                    pmsArchivesRecordMapper.updateByPrimaryKeySelective(willDeletedRecord);
                });
            }

            Date now = new Date();
            PmsArchivesRecord willSavedRecord = new PmsArchivesRecord();
            willSavedRecord.setId(IDGenerator.nextSnowflakeId());
            willSavedRecord.setArchivesId(param.getFirstAidId());
            willSavedRecord.setCode(codeAndAnswer.getQuestionCode());
            willSavedRecord.setAnswer(codeAndAnswer.getAnswerString());
            willSavedRecord.setCreatedAt(now);
            willSavedFirstAidRecordList.add(willSavedRecord);
        }

        //批量保存
        batchSave(willSavedFirstAidRecordList);
    }

    @Override
    public void batchSave(List<PmsArchivesRecord> list) {
        int max = 2000;
        for (int start = 0; start < list.size(); start += max) {
            pmsArchivesDao.batchInsert(list.subList(start,
                    start + (Math.min(list.size() - start, max)))
            );
        }
    }

    private PmsArchives validateFirstAidWhenModified(Long firstAidId) {
        //1. 验证急救信息
        PmsArchives pmsArchives = pmsArchivesMapper.selectByPrimaryKey(firstAidId);
        if (pmsArchives == null) {
            throw new BaseException(ErrorConstants.FIRST_AID_NOT_FOUND, firstAidId + "");
        }
        return pmsArchives;
    }

    /**
     * 验证急救数据，抛出异常
     *
     * @param codeAndAnswerList
     */
    private void validateFirstAidRecords(List<AmsFirstAidDto.SaveAidRecord.CodeAndAnswer> codeAndAnswerList) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        //TODO
        for (AmsFirstAidDto.SaveAidRecord.CodeAndAnswer andAnswer : codeAndAnswerList) {
            UserConstants.QuestionCode code = BaseEnum.keyOf(UserConstants.QuestionCode.class, andAnswer.getQuestionCode());
            List<String> answer = andAnswer.getAnswer();
            if (CollectionUtil.isEmpty(answer)) {
                continue;
            }
            String s = answer.get(0);
            if (StrUtil.isEmpty(s)) {
                continue;
            }
            if (code != null) {
                switch (code) {
                    case JBXX_FBSJ:
                    case JBXX_ZY_TIME:
                    case JBXX_DY_TIME:
                    case JBXX_TZCZYS_TIME:
                    case JBXX_CZYSDC_TIME:
                    case RYPG_BLOOD_REPORT_TIME:
                    case RYPG_ECG_TIME:
                    case RYPG_CT_DD_TIME:
                    case RYPG_CT_JCKS_TIME:
                    case RYPG_CT_JCWB_TIME:
                    case RYPG_CT_LK_TIME:
                    case JMRS_TIME:
                        try {
                            andAnswer.setAnswer(CollectionUtil.newArrayList(sdf.format(sdf.parse(s))));
                        } catch (Exception e) {
                            throw new BaseException(ErrorConstants.TIME_CASE);
                        }
                        break;
                    default:
                        break;
                }
            }
        }
    }

    /**
     * 补充信息
     *
     * @param codeAndAnswerList
     */
    private List<AmsFirstAidDto.SaveAidRecord.CodeAndAnswer> supplement(List<AmsFirstAidDto.SaveAidRecord.CodeAndAnswer> codeAndAnswerList) {
        List<AmsFirstAidDto.SaveAidRecord.CodeAndAnswer> list = new ArrayList<>();
        for (AmsFirstAidDto.SaveAidRecord.CodeAndAnswer andAnswer : codeAndAnswerList) {
            UserConstants.QuestionCode code = BaseEnum.keyOf(UserConstants.QuestionCode.class, andAnswer.getQuestionCode());
            List<String> answer = andAnswer.getAnswer();
            log.info("补充信息:{},{}", code, answer);
            if (CollectionUtil.isEmpty(answer) || StrUtil.isEmpty(answer.get(0))) {
                switch (code) {
                    case JMRS_TH_TIME:
                        try {
                            andAnswer.setAnswer(CollectionUtil.newArrayList(DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss")));
                        } catch (Exception e) {
                            System.out.println("谈话开始时间错误");
                        }
                }
                continue;
            }
            String s = answer.get(0);
            if (StrUtil.isEmpty(s)) {
                continue;
            }
            if (code != null) {
                switch (code) {
                    case RYPG_WEIGHT: {
                        //补充 团注剂量、静滴剂量  计算公式: 体重=A、剂量=A*0.9、团注=剂量*0.1
                        List<String> weightList = andAnswer.getAnswer();
                        if (CollectionUtil.isEmpty(weightList)) {
                            continue;
                        }
                        BigDecimal weight = new BigDecimal(weightList.get(0));
                        //剂量=A*0.9
                        BigDecimal jiliang = weight.multiply(new BigDecimal(0.9)).setScale(2, BigDecimal.ROUND_HALF_UP);
                        //团注=剂量*0.1
                        BigDecimal tuanzhujiliang = jiliang.multiply(new BigDecimal(0.1)).setScale(2, BigDecimal.ROUND_HALF_UP);
                        //静滴=剂量*0.9
                        BigDecimal jingdijiliang = jiliang.multiply(new BigDecimal(0.9)).setScale(2, BigDecimal.ROUND_HALF_UP);

                        AmsFirstAidDto.SaveAidRecord.CodeAndAnswer codeAndAnswer = new AmsFirstAidDto.SaveAidRecord.CodeAndAnswer();
                        codeAndAnswer.setAnswer(CollectionUtil.newArrayList(tuanzhujiliang.toString()));
                        codeAndAnswer.setQuestionCode(JMRS_TZJL.getKey());
                        codeAndAnswer.setTime(new Date());
                        list.add(codeAndAnswer);

                        AmsFirstAidDto.SaveAidRecord.CodeAndAnswer andAnswer1 = new AmsFirstAidDto.SaveAidRecord.CodeAndAnswer();
                        andAnswer1.setAnswer(CollectionUtil.newArrayList(jingdijiliang.toString()));
                        andAnswer1.setQuestionCode(JMRS_JDJL.getKey());
                        andAnswer1.setTime(new Date());
                        list.add(andAnswer1);
                        break;
                    }
                    case JMRS_ZQTY_PIC: {
                        AmsFirstAidDto.SaveAidRecord.CodeAndAnswer codeAndAnswer = new AmsFirstAidDto.SaveAidRecord.CodeAndAnswer();
                        codeAndAnswer.setAnswer(CollectionUtil.newArrayList(DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss")));
                        codeAndAnswer.setQuestionCode(JMRS_ZQTY_TIME.getKey());
                        codeAndAnswer.setTime(new Date());
                        list.add(codeAndAnswer);
                        break;
                    }

                    case JMRS_TIME: {
                        AmsFirstAidDto.SaveAidRecord.CodeAndAnswer codeAndAnswer = new AmsFirstAidDto.SaveAidRecord.CodeAndAnswer();
                        codeAndAnswer.setAnswer(CollectionUtil.newArrayList("是"));
                        codeAndAnswer.setQuestionCode(JMRS_Y.getKey());
                        codeAndAnswer.setTime(new Date());
                        list.add(codeAndAnswer);
                        break;
                    }
                }
            }
        }
        codeAndAnswerList.addAll(list);
        return codeAndAnswerList;
    }
}
